package com.ciaj.module.sys.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ciaj.base.annotation.OperationLog;
import com.ciaj.base.bean.PasswordEntity;
import com.ciaj.base.bean.ResponseEntity;
import com.ciaj.base.bean.TokenEntity;
import com.ciaj.base.comm.constant.DefaultConstant;
import com.ciaj.base.comm.utils.CommUtil;
import com.ciaj.base.comm.utils.PdUtil;
import com.ciaj.base.comm.utils.ShiroUtils;
import com.ciaj.base.comm.utils.StringUtil;
import com.ciaj.base.exception.BsRException;
import com.ciaj.module.sys.controller.form.LoginForm;
import com.ciaj.module.sys.entity.po.SysAuth;
import com.ciaj.module.sys.entity.po.SysMenu;
import com.ciaj.module.sys.entity.po.SysUser;
import com.ciaj.module.sys.entity.vo.ShiroUser;
import com.ciaj.module.sys.service.ISysAuthService;
import com.ciaj.module.sys.service.ISysMenuService;
import com.ciaj.module.sys.service.ISysUserService;
import io.swagger.annotations.Api;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresUser;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @Author: Ciaj.
 * @Date: 2018/6/19 14:27
 * @Description:
 */
@RestController
@RequestMapping("/api/ciaj-sys")
@Api(tags = "系统-管理")
public class SysApi {

    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private ISysAuthService sysAuthService;
    @Autowired
    private ISysMenuService sysMenuService;


    /**
     * 登录方法
     *
     * @param loginForm
     * @return
     */
    @OperationLog(operation = "系统-登录", content = "用户登录")
    @ResponseBody
    @PostMapping("/login")
    public ResponseEntity<TokenEntity> login(@RequestBody LoginForm loginForm) {
        Boolean loginFlag = false;
        for (DefaultConstant.LoginClient value : DefaultConstant.LoginClient.values()) {
            if (value.name().equalsIgnoreCase(loginForm.getLoginClient())) {
                loginFlag = true;
                break;
            }
        }
        if (!loginFlag) throw new BsRException("登录方式不正确");

        try {
            Subject subject = ShiroUtils.getSubject();
            UsernamePasswordToken token = new UsernamePasswordToken(loginForm.getAccount(), loginForm.getPassword());
            token.setRememberMe(loginForm.getRememberMe());
            subject.login(token);
        } catch (UnknownAccountException e) {
            return ResponseEntity.error(e.getMessage());
        } catch (IncorrectCredentialsException e) {
            throw new BsRException("账号或密码不正确");
        } catch (LockedAccountException e) {
            throw new BsRException("账号已被锁定,请联系管理员");
        } catch (AuthenticationException e) {
            throw new BsRException("账户验证失败");
        }

        return new ResponseEntity<TokenEntity>().put(new TokenEntity(ShiroUtils.getSession().getId().toString()));
    }


    /**
     * 注册方法
     *
     * @param loginForm
     * @return
     */
    @OperationLog(operation = "系统-注册", content = "用户注册")
    @ResponseBody
    @PostMapping("/register")
    public ResponseEntity register(@RequestBody LoginForm loginForm) {
        if (StringUtil.isBlank(loginForm.getAccount())) throw new BsRException("用户名不能为空");
        final PasswordEntity p = PdUtil.getPassword(loginForm.getPassword());
        SysUser user = sysUserService.getSysUserByAccount(loginForm.getAccount());
        if (user != null) throw new BsRException("账号已经存在");
        SysUser sysUser = new SysUser();

        sysUser.setAccount(loginForm.getAccount());
        sysUser.setUsername(loginForm.getAccount());
        sysUser.setNickname(loginForm.getAccount());
        sysUserService.save(sysUser);

        SysAuth sysAuth = new SysAuth();
        sysAuth.setUserId(sysUser.getId());
        sysAuth.setPassword(p.getPassword());
        sysAuth.setSalt(p.getSalt());
        sysAuthService.save(sysAuth);
        return ResponseEntity.success("注册成功");
    }


    /**
     * 获取导航菜单
     *
     * @return
     */
    @OperationLog(operation = "系统-导航", content = "获取导航菜单")
    @RequiresUser
    @ResponseBody
    @GetMapping("/menu/nav")
    public ResponseEntity<SysMenu> nav() {
        List<SysMenu> list = sysMenuService.selectNav();
        return ResponseEntity.success().put(list);
    }


    /**
     * PC注册方法
     *
     * @param entity
     * @return
     */
    @OperationLog(operation = "系统-注册", content = "PC注册方法")
    @ResponseBody
    @PostMapping("/pc/register")
    public ResponseEntity pcRegister(@RequestBody SysUser entity) {
        if (StringUtil.isBlank(entity.getMobile())) throw new BsRException("手机号不能为空");

        SysUser user = sysUserService.getSysUserByAccount(entity.getAccount());
        if (user != null) throw new BsRException("账号已经存在");
        String password = user.getMobile().substring(entity.getMobile().length() - 6);
        final PasswordEntity p = PdUtil.getPassword(password);
        sysUserService.save(entity);

        SysAuth sysAuth = new SysAuth();
        sysAuth.setUserId(entity.getId());
        sysAuth.setPassword(p.getPassword());
        sysAuth.setSalt(p.getSalt());
        sysAuthService.save(sysAuth);

        return ResponseEntity.success("添加成功").put(entity);
    }

    /**
     * 获取当前登录用户
     *
     * @return
     */
    @OperationLog(operation = "系统-用户", content = "获取当前登录用户")
    @RequiresUser
    @ResponseBody
    @GetMapping("/user/info")
    public ResponseEntity userInfo() {
        final Object loginUser = CommUtil.getLoginUser();
        return ResponseEntity.success().put(loginUser);
    }


    /**
     * 更新当前登录用户角色
     *
     * @return
     */
    @OperationLog(operation = "系统-用户", content = "更新当前登录用户角色")
    @RequiresUser
    @ResponseBody
    @PostMapping("/user/jobChange/{jobId}")
    public ResponseEntity jobChange(@PathVariable("jobId") String jobId) {
        ShiroUser shiroUser = sysUserService.shiroUserJobChange(jobId);
        return ResponseEntity.success().put(shiroUser);
    }

    /**
     * 密码修改
     *
     * @param password
     * @param newPassword
     * @return
     */
    @OperationLog(operation = "系统-用户", content = "密码修改")
    @RequiresUser
    @ResponseBody
    @PostMapping("/user/password")
    public ResponseEntity updatePassword(String password, String newPassword) {
        if (StringUtil.isBlank(password) || StringUtil.isBlank(newPassword)) {
            return ResponseEntity.error("密码不能为空");
        }
        final ShiroUser loginUser = (ShiroUser) CommUtil.getLoginUser();
        SysAuth sysAuth = sysAuthService.getOne(new QueryWrapper<SysAuth>().lambda().eq(SysAuth::getUserId, loginUser.getId()));

        final PasswordEntity password1 = PdUtil.getPassword(password, sysAuth.getSalt());

        if (!sysAuth.getPassword().equals(password1.getPassword())) {
            return ResponseEntity.error("原密码不正确");
        }
        final PasswordEntity password2 = PdUtil.getPassword(newPassword);
        sysAuth.setId(sysAuth.getId());
        sysAuth.setPassword(password2.getPassword());
        sysAuth.setSalt(password2.getSalt());
        sysAuthService.updateById(sysAuth);
        return ResponseEntity.success();
    }


    /**
     * 用户密码修改
     *
     * @param userId
     * @param newPassword
     * @return
     */
    @OperationLog(operation = "系统-用户", content = "用户密码修改")
    @ResponseBody
    @RequiresPermissions("sys:user:password:update")
    @PostMapping("/user/password/update")
    public ResponseEntity updateUserPassword(String userId, String newPassword) {
        if (StringUtil.isBlank(newPassword)) {
            return ResponseEntity.error("密码不能为空");
        }
        SysAuth sysAuth = sysAuthService.getOne(new QueryWrapper<SysAuth>().lambda().eq(SysAuth::getUserId, userId));

        final PasswordEntity password2 = PdUtil.getPassword(newPassword);
        sysAuth.setId(sysAuth.getId());
        sysAuth.setPassword(password2.getPassword());
        sysAuth.setSalt(password2.getSalt());
        sysAuthService.updateById(sysAuth);
        return ResponseEntity.success();
    }


    /**
     * 登出方法
     *
     * @return
     */
    @OperationLog(operation = "系统-登出", content = "退出登录")
    @GetMapping("/logout")
    public ResponseEntity logout() {
        ShiroUtils.logout();
        return ResponseEntity.success();
    }


    /**
     * 登出方法
     *
     * @return
     */
    @OperationLog(operation = "系统-登出", content = "退出登录")
    @GetMapping("/401")
    public ResponseEntity error401() {
        return ResponseEntity.error("没有权限，请联系管理员授权");
    }
}
